package com.example.springstatemachine.configuration;

import com.example.springstatemachine.action.SubmitAction;
import com.example.springstatemachine.consant.DocumentEvents;
import com.example.springstatemachine.consant.DocumentStates;
import com.example.springstatemachine.listener.DocumentStateChangeListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;

import java.util.EnumSet;

@Configuration
@EnableStateMachine
public class DocumentStateMachineConfig extends StateMachineConfigurerAdapter<DocumentStates, DocumentEvents> {

    @Autowired
    private DocumentStateChangeListener documentStateChangeListener;

    @Autowired
    private SubmitAction submitAction;
    @Override
    public void configure(StateMachineStateConfigurer<DocumentStates, DocumentEvents> states) throws Exception {
        states
            .withStates()
                .initial(DocumentStates.DRAFT)
                .states(EnumSet.allOf(DocumentStates.class));
    }

    @Override
    public void configure(StateMachineTransitionConfigurer<DocumentStates, DocumentEvents> transitions) throws Exception {
        transitions
            .withExternal().source(DocumentStates.DRAFT).target(DocumentStates.SUBMITTED).event(DocumentEvents.SUBMIT).action(submitAction)
            .and()
            .withExternal().source(DocumentStates.SUBMITTED).target(DocumentStates.APPROVED).event(DocumentEvents.APPROVE)
            .and()
            .withExternal().source(DocumentStates.SUBMITTED).target(DocumentStates.REJECTED).event(DocumentEvents.REJECT)
            .and()
            .withExternal().source(DocumentStates.APPROVED).target(DocumentStates.PUBLISHED).event(DocumentEvents.PUBLISH);
    }

    @Override
    public void configure(StateMachineConfigurationConfigurer<DocumentStates, DocumentEvents> config) throws Exception {
        config
                .withConfiguration()
                .listener(documentStateChangeListener);
    }
}